"""Tabulated and generated quadrature points for various reference domains."""

import numpy as np

from typing import Tuple


def get_quadrature(refdom: str, norder: int) -> Tuple[np.ndarray, np.ndarray]:
    """Return a nth order accurate quadrature rule for different reference
    domains.
    
    Parameters
    ----------
    refdom
        The name of the reference domain. Valid reference domains can be found
        in the following table.
    
        +-------+-----------------+----------------+
        | Name  | Corner points   | Maximum order  |
        +-------+-----------------+----------------+
        | point | N.A.            | infty          |
        +-------+-----------------+----------------+
        | line  | 0, 1            | infty          |
        +-------+-----------------+----------------+
        | tri   | (0,0) (0,1)     | 19             |
        |       | (1,0)           |                |
        +-------+-----------------+----------------+
        | quad  | (-1,-1) (1,-1)  | infty          |
        |       | (1,1) (-1,1)    |                |
        +-------+-----------------+----------------+
        | tet   | (0,0,0) (0,0,1) | 4              |
        |       | (0,1,0) (1,0,0) |                |
        +-------+-----------------+----------------+
        | hex   | (-1,-1,-1),     | infty          |
        |       | (1,1,1), etc.   |                |
        +-------+-----------------+----------------+

        norder
            The polynomial order upto which the requested quadrature rule is
            accurate.

    Returns
    -------
        An array of quadrature points (Ndim x Nqp) and an array of quadrature
        weights (Nqp).

    """
    if refdom is "tri":
        return get_quadrature_tri(norder)
    elif refdom is "tet":
        return get_quadrature_tet(norder)
    elif refdom is "line": # [0,1]
        return get_quadrature_line(norder)
    elif refdom is "point":
        return get_quadrature_point(norder)
    elif refdom is "quad": # (-1,-1) (1,-1) (1,1) (-1,1)
        X, W = get_quadrature_line(norder)
        # generate tensor product rule from 1D rule
        A, B = np.meshgrid(X, X)
        Y = 2.0*np.vstack((A.flatten(order='F'),
                           B.flatten(order='F'))) - 1.0
        # transform weights
        A, B = np.meshgrid(2*W, 2*W)
        Z = A*B 
        W = Z.flatten(order='F')
        return Y, W
    elif refdom is "hex": # (-1,-1,-1), (1,1,1), etc.
        X, W = get_quadrature_line(norder)
        # generate tensor product rule from 1D rule
        A, B, C = np.meshgrid(X, X, X)
        Y = 2.0*np.vstack((A.flatten(order='F'),
                           B.flatten(order='F'),
                           C.flatten(order='F'))) - 1.0
        # transform weights
        A, B, C = np.meshgrid(2*W, 2*W, 2*W)
        Z = A*B*C
        W = Z.flatten(order='F')
        return Y, W
    else:
        raise NotImplementedError("The given mesh type is not supported!")


def get_quadrature_tet(norder: int) -> Tuple[np.ndarray, np.ndarray]:
    """Return a nth order accurate quadrature rule for the reference
    tetrahedron (0,0,0) (0,0,1) (0,1,0) (1,0,0)."""
    if norder <= 1:
        norder = 2
    try:
        return {
            2: (np.array([[0.5854101966249685, 0.1381966011250105, 0.1381966011250105, 0.1381966011250105], \
                          [0.1381966011250105, 0.1381966011250105, 0.1381966011250105, 0.5854101966249685], \
                          [0.1381966011250105, 0.1381966011250105, 0.5854101966249685, 0.1381966011250105]]), \
                np.array([0.2500000000000000, 0.2500000000000000, 0.2500000000000000, 0.2500000000000000]) / 6.),
            3: (np.array([[0.2500000000000000, 0.5000000000000000, 0.1666666666666667, 0.1666666666666667, 0.1666666666666667], \
                          [0.2500000000000000, 0.1666666666666667, 0.1666666666666667, 0.1666666666666667, 0.5000000000000000], \
                          [0.2500000000000000, 0.1666666666666667, 0.1666666666666667, 0.5000000000000000, 0.1666666666666667]]), \
                np.array([-0.8000000000000000, 0.4500000000000000, 0.4500000000000000, 0.4500000000000000,
                          0.4500000000000000]) / 6.),
            4: (np.array([[0.2500000000000000, 0.7857142857142857, 0.0714285714285714, 0.0714285714285714,
                           0.0714285714285714, 0.1005964238332008, 0.3994035761667992, 0.3994035761667992,
                           0.3994035761667992, 0.1005964238332008, 0.1005964238332008], \
                          [0.2500000000000000, 0.0714285714285714, 0.0714285714285714, 0.0714285714285714,
                           0.7857142857142857, 0.3994035761667992, 0.1005964238332008, 0.3994035761667992,
                           0.1005964238332008, 0.3994035761667992, 0.1005964238332008], \
                          [0.2500000000000000, 0.0714285714285714, 0.0714285714285714, 0.7857142857142857,
                           0.0714285714285714, 0.3994035761667992, 0.3994035761667992, 0.1005964238332008,
                           0.1005964238332008, 0.1005964238332008, 0.3994035761667992]]), \
                np.array([-0.0789333333333333, 0.0457333333333333, 0.0457333333333333, 0.0457333333333333,
                          0.0457333333333333, 0.1493333333333333, 0.1493333333333333, 0.1493333333333333,
                          0.1493333333333333, 0.1493333333333333, 0.1493333333333333]) / 6.)
        }[norder]  # last one available from http://www.cfd-online.com/Wiki/Code:_Quadrature_on_Tetrahedra
    except:
        raise NotImplementedError("The requested order of quadrature " +
                                  "is not tabulated.")


def get_quadrature_tri(norder: int) -> Tuple[np.ndarray, np.ndarray]:
    """Return a nth order accurate quadrature rule for the reference triangle
    (0,0) (0,1) (1,0)."""
    if norder <= 1:
        norder = 2
    try:
        return {
            2: (np.array([[1.666666666666666666666e-01, 6.666666666666666666666e-01, 1.666666666666666666666e-01],
                          [1.666666666666666666666e-01, 1.666666666666666666666e-01, 6.666666666666666666666e-01]]),
                np.array([1.666666666666666666666e-01, 1.666666666666666666666e-01, 1.666666666666666666666e-01])),
            3: (np.array([[0.333333333333333, 0.2, 0.6, 0.2], [0.333333333333333, 0.6, 0.2, 0.2]]),
                np.array([-0.28125, 0.260416666666667, 0.260416666666667, 0.260416666666667])),
            4: (np.array([[0.445948490915965, 0.0915762135097699, 0.10810301816807, 0.816847572980459,
                           0.445948490915965, 0.091576213509771],
                          [0.10810301816807, 0.816847572980459, 0.445948490915965, 0.091576213509771, 0.445948490915965,
                           0.0915762135097699]]), np.array(
                [0.111690794839006, 0.054975871827661, 0.111690794839006, 0.054975871827661, 0.111690794839006,
                 0.054975871827661])),
            5: (np.array([[0.333333333333333, 0.470142064105115, 0.101286507323457, 0.05971587178977, 0.797426985353087,
                           0.470142064105115, 0.101286507323456],
                          [0.333333333333333, 0.05971587178977, 0.797426985353087, 0.470142064105115, 0.101286507323456,
                           0.470142064105115, 0.101286507323457]]), np.array(
                [0.1125, 0.066197076394253, 0.0629695902724135, 0.066197076394253, 0.0629695902724135,
                 0.066197076394253, 0.0629695902724135])),
            6: (np.array([[0.249286745170911, 0.0630890144915021, 0.501426509658179, 0.873821971016996,
                           0.24928674517091, 0.063089014491502, 0.636502499121399, 0.310352451033784, 0.053145049844817,
                           0.053145049844817, 0.310352451033784, 0.636502499121399],
                          [0.501426509658179, 0.873821971016996, 0.24928674517091, 0.063089014491502, 0.249286745170911,
                           0.0630890144915021, 0.053145049844817, 0.053145049844817, 0.310352451033784,
                           0.636502499121399, 0.636502499121399, 0.310352451033784]]), np.array(
                [0.0583931378631895, 0.0254224531851035, 0.0583931378631895, 0.0254224531851035, 0.0583931378631895,
                 0.0254224531851035, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187,
                 0.041425537809187, 0.041425537809187])),
            7: (np.array([[0.333333333333333, 0.26034596607904, 0.065130102902216, 0.47930806784192, 0.869739794195568,
                           0.26034596607904, 0.065130102902216, 0.63844418856981, 0.312865496004874, 0.048690315425316,
                           0.048690315425316, 0.312865496004874, 0.63844418856981],
                          [0.333333333333333, 0.47930806784192, 0.869739794195568, 0.26034596607904, 0.065130102902216,
                           0.26034596607904, 0.065130102902216, 0.048690315425316, 0.048690315425316, 0.312865496004874,
                           0.63844418856981, 0.63844418856981, 0.312865496004874]]), np.array(
                [-0.074785022233841, 0.087807628716604, 0.026673617804419, 0.087807628716604, 0.026673617804419,
                 0.087807628716604, 0.026673617804419, 0.0385568804451285, 0.0385568804451285, 0.0385568804451285,
                 0.0385568804451285, 0.0385568804451285, 0.0385568804451285])),
            8: (np.array([[0.333333333333333, 0.459292588292723, 0.17056930775176, 0.0505472283170311,
                           0.081414823414554, 0.65886138449648, 0.898905543365938, 0.459292588292723, 0.17056930775176,
                           0.050547228317031, 0.728492392955404, 0.263112829634638, 0.008394777409958,
                           0.008394777409958, 0.263112829634638, 0.728492392955404],
                          [0.333333333333333, 0.081414823414554, 0.65886138449648, 0.898905543365938, 0.459292588292723,
                           0.17056930775176, 0.050547228317031, 0.459292588292723, 0.17056930775176, 0.0505472283170311,
                           0.008394777409958, 0.008394777409958, 0.263112829634638, 0.728492392955404,
                           0.728492392955404, 0.263112829634638]]), np.array(
                [0.0721578038388935, 0.0475458171336425, 0.051608685267359, 0.016229248811599, 0.0475458171336425,
                 0.051608685267359, 0.016229248811599, 0.0475458171336425, 0.051608685267359, 0.016229248811599,
                 0.0136151570872175, 0.0136151570872175, 0.0136151570872175, 0.0136151570872175, 0.0136151570872175,
                 0.0136151570872175])),
            9: (np.array([[0.333333333333333, 0.489682519198737, 0.437089591492936, 0.188203535619032,
                           0.0447295133944519, 0.020634961602525, 0.125820817014127, 0.623592928761935,
                           0.910540973211095, 0.489682519198738, 0.437089591492937, 0.188203535619033,
                           0.044729513394453, 0.741198598784498, 0.221962989160766, 0.036838412054736,
                           0.036838412054736, 0.221962989160766, 0.741198598784498],
                          [0.333333333333333, 0.020634961602525, 0.125820817014127, 0.623592928761935,
                           0.910540973211095, 0.489682519198738, 0.437089591492937, 0.188203535619033,
                           0.044729513394453, 0.489682519198737, 0.437089591492936, 0.188203535619032,
                           0.0447295133944519, 0.036838412054736, 0.036838412054736, 0.221962989160766,
                           0.741198598784498, 0.741198598784498, 0.221962989160766]]), np.array(
                [0.0485678981413995, 0.0156673501135695, 0.038913770502387, 0.039823869463605, 0.012788837829349,
                 0.0156673501135695, 0.038913770502387, 0.039823869463605, 0.012788837829349, 0.0156673501135695,
                 0.038913770502387, 0.039823869463605, 0.012788837829349, 0.0216417696886445, 0.0216417696886445,
                 0.0216417696886445, 0.0216417696886445, 0.0216417696886445, 0.0216417696886445])),
            10: (np.array([[0.333333333333333, 0.485577633383658, 0.109481575485037, 0.028844733232685,
                            0.781036849029926, 0.485577633383657, 0.109481575485037, 0.550352941820999,
                            0.728323904597411, 0.923655933587501, 0.307939838764121, 0.246672560639903, 0.0668032510122,
                            0.14170721941488, 0.025003534762686, 0.009540815400299, 0.14170721941488, 0.025003534762686,
                            0.009540815400299, 0.307939838764121, 0.246672560639903, 0.0668032510122, 0.550352941820999,
                            0.728323904597411, 0.923655933587501],
                           [0.333333333333333, 0.028844733232685, 0.781036849029926, 0.485577633383657,
                            0.109481575485037, 0.485577633383658, 0.109481575485037, 0.14170721941488,
                            0.025003534762686, 0.009540815400299, 0.14170721941488, 0.025003534762686,
                            0.009540815400299, 0.307939838764121, 0.246672560639903, 0.0668032510122, 0.550352941820999,
                            0.728323904597411, 0.923655933587501, 0.550352941820999, 0.728323904597411,
                            0.923655933587501, 0.307939838764121, 0.246672560639903, 0.0668032510122]]), np.array(
                [0.045408995191377, 0.0183629788782335, 0.022660529717764, 0.0183629788782335, 0.022660529717764,
                 0.0183629788782335, 0.022660529717764, 0.03637895842271, 0.0141636212655285, 0.0047108334818665,
                 0.03637895842271, 0.0141636212655285, 0.0047108334818665, 0.03637895842271, 0.0141636212655285,
                 0.0047108334818665, 0.03637895842271, 0.0141636212655285, 0.0047108334818665, 0.03637895842271,
                 0.0141636212655285, 0.0047108334818665, 0.03637895842271, 0.0141636212655285, 0.0047108334818665])),
            11: (np.array([[0.488217389773805, 0.439724392294461, 0.271210385012116, 0.127576145541586,
                            0.021317350453211, 0.02356522045239, 0.120551215411079, 0.457579229975768,
                            0.744847708916828, 0.957365299093579, 0.488217389773805, 0.43972439229446,
                            0.271210385012116, 0.127576145541586, 0.02131735045321, 0.608943235779788,
                            0.695836086787803, 0.858014033544073, 0.275713269685514, 0.28132558098994,
                            0.116251915907597, 0.115343494534698, 0.022838332222257, 0.02573405054833,
                            0.115343494534698, 0.022838332222257, 0.02573405054833, 0.275713269685514, 0.28132558098994,
                            0.116251915907597, 0.608943235779788, 0.695836086787803, 0.858014033544073],
                           [0.02356522045239, 0.120551215411079, 0.457579229975768, 0.744847708916828,
                            0.957365299093579, 0.488217389773805, 0.43972439229446, 0.271210385012116,
                            0.127576145541586, 0.02131735045321, 0.488217389773805, 0.439724392294461,
                            0.271210385012116, 0.127576145541586, 0.021317350453211, 0.115343494534698,
                            0.022838332222257, 0.02573405054833, 0.115343494534698, 0.022838332222257, 0.02573405054833,
                            0.275713269685514, 0.28132558098994, 0.116251915907597, 0.608943235779788,
                            0.695836086787803, 0.858014033544073, 0.608943235779788, 0.695836086787803,
                            0.858014033544073, 0.275713269685514, 0.28132558098994, 0.116251915907597]]), np.array(
                [0.0128655332202275, 0.021846272269019, 0.0314291121089425, 0.0173980564653545, 0.0030831305257795,
                 0.0128655332202275, 0.021846272269019, 0.0314291121089425, 0.0173980564653545, 0.0030831305257795,
                 0.0128655332202275, 0.021846272269019, 0.0314291121089425, 0.0173980564653545, 0.0030831305257795,
                 0.0201857788831905, 0.0111783866011515, 0.0086581155543295, 0.0201857788831905, 0.0111783866011515,
                 0.0086581155543295, 0.0201857788831905, 0.0111783866011515, 0.0086581155543295, 0.0201857788831905,
                 0.0111783866011515, 0.0086581155543295, 0.0201857788831905, 0.0111783866011515, 0.0086581155543295,
                 0.0201857788831905, 0.0111783866011515, 0.0086581155543295])),
            12: (np.array([[0.488217389773805, 0.439724392294461, 0.271210385012116, 0.127576145541586,
                            0.021317350453211, 0.02356522045239, 0.120551215411079, 0.457579229975768,
                            0.744847708916828, 0.957365299093579, 0.488217389773805, 0.43972439229446,
                            0.271210385012116, 0.127576145541586, 0.02131735045321, 0.608943235779788,
                            0.695836086787803, 0.858014033544073, 0.275713269685514, 0.28132558098994,
                            0.116251915907597, 0.115343494534698, 0.022838332222257, 0.02573405054833,
                            0.115343494534698, 0.022838332222257, 0.02573405054833, 0.275713269685514, 0.28132558098994,
                            0.116251915907597, 0.608943235779788, 0.695836086787803, 0.858014033544073],
                           [0.02356522045239, 0.120551215411079, 0.457579229975768, 0.744847708916828,
                            0.957365299093579, 0.488217389773805, 0.43972439229446, 0.271210385012116,
                            0.127576145541586, 0.02131735045321, 0.488217389773805, 0.439724392294461,
                            0.271210385012116, 0.127576145541586, 0.021317350453211, 0.115343494534698,
                            0.022838332222257, 0.02573405054833, 0.115343494534698, 0.022838332222257, 0.02573405054833,
                            0.275713269685514, 0.28132558098994, 0.116251915907597, 0.608943235779788,
                            0.695836086787803, 0.858014033544073, 0.608943235779788, 0.695836086787803,
                            0.858014033544073, 0.275713269685514, 0.28132558098994, 0.116251915907597]]), np.array(
                [0.0128655332202275, 0.021846272269019, 0.0314291121089425, 0.0173980564653545, 0.0030831305257795,
                 0.0128655332202275, 0.021846272269019, 0.0314291121089425, 0.0173980564653545, 0.0030831305257795,
                 0.0128655332202275, 0.021846272269019, 0.0314291121089425, 0.0173980564653545, 0.0030831305257795,
                 0.0201857788831905, 0.0111783866011515, 0.0086581155543295, 0.0201857788831905, 0.0111783866011515,
                 0.0086581155543295, 0.0201857788831905, 0.0111783866011515, 0.0086581155543295, 0.0201857788831905,
                 0.0111783866011515, 0.0086581155543295, 0.0201857788831905, 0.0111783866011515, 0.0086581155543295,
                 0.0201857788831905, 0.0111783866011515, 0.0086581155543295])),
            13: (np.array([[0.333333333333333, 0.495048184939704, 0.468716635109574, 0.414521336801276,
                            0.229399572042832, 0.11442449519633, 0.024811391363459, 0.009903630120591,
                            0.062566729780852, 0.170957326397447, 0.541200855914337, 0.77115100960734,
                            0.950377217273082, 0.495048184939705, 0.468716635109574, 0.414521336801277,
                            0.229399572042831, 0.11442449519633, 0.024811391363459, 0.63635117456166, 0.690169159986905,
                            0.851409537834241, 0.268794997058761, 0.291730066734288, 0.126357385491669,
                            0.094853828379579, 0.018100773278807, 0.02223307667409, 0.094853828379579,
                            0.018100773278807, 0.02223307667409, 0.268794997058761, 0.291730066734288,
                            0.126357385491669, 0.63635117456166, 0.690169159986905, 0.851409537834241],
                           [0.333333333333333, 0.009903630120591, 0.062566729780852, 0.170957326397447,
                            0.541200855914337, 0.77115100960734, 0.950377217273082, 0.495048184939705,
                            0.468716635109574, 0.414521336801277, 0.229399572042831, 0.11442449519633,
                            0.024811391363459, 0.495048184939704, 0.468716635109574, 0.414521336801276,
                            0.229399572042832, 0.11442449519633, 0.024811391363459, 0.094853828379579,
                            0.018100773278807, 0.02223307667409, 0.094853828379579, 0.018100773278807, 0.02223307667409,
                            0.268794997058761, 0.291730066734288, 0.126357385491669, 0.63635117456166,
                            0.690169159986905, 0.851409537834241, 0.63635117456166, 0.690169159986905,
                            0.851409537834241, 0.268794997058761, 0.291730066734288, 0.126357385491669]]), np.array(
                [0.026260461700401, 0.005640072604665, 0.015711759181227, 0.023536251252097, 0.0236817932681775,
                 0.015583764522897, 0.003987885732537, 0.005640072604665, 0.015711759181227, 0.023536251252097,
                 0.0236817932681775, 0.015583764522897, 0.003987885732537, 0.005640072604665, 0.015711759181227,
                 0.023536251252097, 0.0236817932681775, 0.015583764522897, 0.003987885732537, 0.018424201364366,
                 0.008700731651911, 0.0077608934195225, 0.018424201364366, 0.008700731651911, 0.0077608934195225,
                 0.018424201364366, 0.008700731651911, 0.0077608934195225, 0.018424201364366, 0.008700731651911,
                 0.0077608934195225, 0.018424201364366, 0.008700731651911, 0.0077608934195225, 0.018424201364366,
                 0.008700731651911, 0.0077608934195225])),
            14: (np.array([[0.488963910362178, 0.417644719340454, 0.273477528308838, 0.177205532412544,
                            0.0617998830908719, 0.019390961248701, 0.022072179275643, 0.164710561319092,
                            0.453044943382323, 0.645588935174913, 0.876400233818255, 0.961218077502598,
                            0.488963910362179, 0.417644719340454, 0.273477528308839, 0.177205532412543,
                            0.061799883090873, 0.019390961248701, 0.770608554774996, 0.570222290846683,
                            0.686980167808088, 0.879757171370171, 0.172266687821356, 0.336861459796345,
                            0.298372882136258, 0.118974497696957, 0.057124757403648, 0.092916249356972,
                            0.014646950055654, 0.001268330932872, 0.057124757403648, 0.092916249356972,
                            0.014646950055654, 0.001268330932872, 0.172266687821356, 0.336861459796345,
                            0.298372882136258, 0.118974497696957, 0.770608554774996, 0.570222290846683,
                            0.686980167808088, 0.879757171370171],
                           [0.022072179275643, 0.164710561319092, 0.453044943382323, 0.645588935174913,
                            0.876400233818255, 0.961218077502598, 0.488963910362179, 0.417644719340454,
                            0.273477528308839, 0.177205532412543, 0.061799883090873, 0.019390961248701,
                            0.488963910362178, 0.417644719340454, 0.273477528308838, 0.177205532412544,
                            0.0617998830908719, 0.019390961248701, 0.057124757403648, 0.092916249356972,
                            0.014646950055654, 0.001268330932872, 0.057124757403648, 0.092916249356972,
                            0.014646950055654, 0.001268330932872, 0.172266687821356, 0.336861459796345,
                            0.298372882136258, 0.118974497696957, 0.770608554774996, 0.570222290846683,
                            0.686980167808088, 0.879757171370171, 0.770608554774996, 0.570222290846683,
                            0.686980167808088, 0.879757171370171, 0.172266687821356, 0.336861459796345,
                            0.298372882136258, 0.118974497696957]]), np.array(
                [0.0109417906847145, 0.0163941767720625, 0.025887052253646, 0.0210812943684965, 0.0072168498348885,
                 0.0024617018012, 0.0109417906847145, 0.0163941767720625, 0.025887052253646, 0.0210812943684965,
                 0.0072168498348885, 0.0024617018012, 0.0109417906847145, 0.0163941767720625, 0.025887052253646,
                 0.0210812943684965, 0.0072168498348885, 0.0024617018012, 0.012332876606282, 0.0192857553935305,
                 0.007218154056767, 0.0025051144192505, 0.012332876606282, 0.0192857553935305, 0.007218154056767,
                 0.0025051144192505, 0.012332876606282, 0.0192857553935305, 0.007218154056767, 0.0025051144192505,
                 0.012332876606282, 0.0192857553935305, 0.007218154056767, 0.0025051144192505, 0.012332876606282,
                 0.0192857553935305, 0.007218154056767, 0.0025051144192505, 0.012332876606282, 0.0192857553935305,
                 0.007218154056767, 0.0025051144192505])),
            15: (np.array([[0.333333333333333, 0.497170540556774, 0.482176322624624, 0.450239969020781,
                            0.400266239377397, 0.252141267970952, 0.162047004658462, 0.0758758822607461,
                            0.015654726967822, 0.005658918886452, 0.035647354750751, 0.099520061958437,
                            0.199467521245206, 0.495717464058095, 0.675905990683077, 0.848248235478508,
                            0.968690546064356, 0.497170540556774, 0.482176322624625, 0.450239969020782,
                            0.400266239377397, 0.252141267970953, 0.162047004658461, 0.075875882260746,
                            0.015654726967822, 0.655493203809423, 0.57233759053202, 0.626001190286227,
                            0.796427214974071, 0.75235100593773, 0.904625504095608, 0.334319867363658,
                            0.292221537796944, 0.31957488542319, 0.190704224192292, 0.180483211648746,
                            0.080711313679564, 0.010186928826919, 0.135440871671036, 0.054423924290583,
                            0.012868560833637, 0.067165782413524, 0.014663182224828, 0.010186928826919,
                            0.135440871671036, 0.054423924290583, 0.012868560833637, 0.067165782413524,
                            0.014663182224828, 0.334319867363658, 0.292221537796944, 0.31957488542319,
                            0.190704224192292, 0.180483211648746, 0.080711313679564, 0.655493203809423,
                            0.57233759053202, 0.626001190286227, 0.796427214974071, 0.75235100593773,
                            0.904625504095608],
                           [0.333333333333333, 0.005658918886452, 0.035647354750751, 0.099520061958437,
                            0.199467521245206, 0.495717464058095, 0.675905990683077, 0.848248235478508,
                            0.968690546064356, 0.497170540556774, 0.482176322624625, 0.450239969020782,
                            0.400266239377397, 0.252141267970953, 0.162047004658461, 0.075875882260746,
                            0.015654726967822, 0.497170540556774, 0.482176322624624, 0.450239969020781,
                            0.400266239377397, 0.252141267970952, 0.162047004658462, 0.0758758822607461,
                            0.015654726967822, 0.010186928826919, 0.135440871671036, 0.054423924290583,
                            0.012868560833637, 0.067165782413524, 0.014663182224828, 0.010186928826919,
                            0.135440871671036, 0.054423924290583, 0.012868560833637, 0.067165782413524,
                            0.014663182224828, 0.334319867363658, 0.292221537796944, 0.31957488542319,
                            0.190704224192292, 0.180483211648746, 0.080711313679564, 0.655493203809423,
                            0.57233759053202, 0.626001190286227, 0.796427214974071, 0.75235100593773, 0.904625504095608,
                            0.655493203809423, 0.57233759053202, 0.626001190286227, 0.796427214974071, 0.75235100593773,
                            0.904625504095608, 0.334319867363658, 0.292221537796944, 0.31957488542319,
                            0.190704224192292, 0.180483211648746, 0.080711313679564]]), np.array(
                [0.0167185996454015, 0.0025467077202535, 0.007335432263819, 0.012175439176836, 0.0155537754344845,
                 0.01562855560931, 0.0124078271698325, 0.0070280365352785, 0.0015973380868895, 0.0025467077202535,
                 0.007335432263819, 0.012175439176836, 0.0155537754344845, 0.01562855560931, 0.0124078271698325,
                 0.0070280365352785, 0.0015973380868895, 0.0025467077202535, 0.007335432263819, 0.012175439176836,
                 0.0155537754344845, 0.01562855560931, 0.0124078271698325, 0.0070280365352785, 0.0015973380868895,
                 0.0040598276594965, 0.0134028711415815, 0.009229996605411, 0.004238434267164, 0.0091463983850125,
                 0.0033328160020825, 0.0040598276594965, 0.0134028711415815, 0.009229996605411, 0.004238434267164,
                 0.0091463983850125, 0.0033328160020825, 0.0040598276594965, 0.0134028711415815, 0.009229996605411,
                 0.004238434267164, 0.0091463983850125, 0.0033328160020825, 0.0040598276594965, 0.0134028711415815,
                 0.009229996605411, 0.004238434267164, 0.0091463983850125, 0.0033328160020825, 0.0040598276594965,
                 0.0134028711415815, 0.009229996605411, 0.004238434267164, 0.0091463983850125, 0.0033328160020825,
                 0.0040598276594965, 0.0134028711415815, 0.009229996605411, 0.004238434267164, 0.0091463983850125,
                 0.0033328160020825])),
            16: (np.array([[0.333333333333333, 0.497170540556774, 0.482176322624624, 0.450239969020781,
                            0.400266239377397, 0.252141267970952, 0.162047004658462, 0.0758758822607461,
                            0.015654726967822, 0.005658918886452, 0.035647354750751, 0.099520061958437,
                            0.199467521245206, 0.495717464058095, 0.675905990683077, 0.848248235478508,
                            0.968690546064356, 0.497170540556774, 0.482176322624625, 0.450239969020782,
                            0.400266239377397, 0.252141267970953, 0.162047004658461, 0.075875882260746,
                            0.015654726967822, 0.655493203809423, 0.57233759053202, 0.626001190286227,
                            0.796427214974071, 0.75235100593773, 0.904625504095608, 0.334319867363658,
                            0.292221537796944, 0.31957488542319, 0.190704224192292, 0.180483211648746,
                            0.080711313679564, 0.010186928826919, 0.135440871671036, 0.054423924290583,
                            0.012868560833637, 0.067165782413524, 0.014663182224828, 0.010186928826919,
                            0.135440871671036, 0.054423924290583, 0.012868560833637, 0.067165782413524,
                            0.014663182224828, 0.334319867363658, 0.292221537796944, 0.31957488542319,
                            0.190704224192292, 0.180483211648746, 0.080711313679564, 0.655493203809423,
                            0.57233759053202, 0.626001190286227, 0.796427214974071, 0.75235100593773,
                            0.904625504095608],
                           [0.333333333333333, 0.005658918886452, 0.035647354750751, 0.099520061958437,
                            0.199467521245206, 0.495717464058095, 0.675905990683077, 0.848248235478508,
                            0.968690546064356, 0.497170540556774, 0.482176322624625, 0.450239969020782,
                            0.400266239377397, 0.252141267970953, 0.162047004658461, 0.075875882260746,
                            0.015654726967822, 0.497170540556774, 0.482176322624624, 0.450239969020781,
                            0.400266239377397, 0.252141267970952, 0.162047004658462, 0.0758758822607461,
                            0.015654726967822, 0.010186928826919, 0.135440871671036, 0.054423924290583,
                            0.012868560833637, 0.067165782413524, 0.014663182224828, 0.010186928826919,
                            0.135440871671036, 0.054423924290583, 0.012868560833637, 0.067165782413524,
                            0.014663182224828, 0.334319867363658, 0.292221537796944, 0.31957488542319,
                            0.190704224192292, 0.180483211648746, 0.080711313679564, 0.655493203809423,
                            0.57233759053202, 0.626001190286227, 0.796427214974071, 0.75235100593773, 0.904625504095608,
                            0.655493203809423, 0.57233759053202, 0.626001190286227, 0.796427214974071, 0.75235100593773,
                            0.904625504095608, 0.334319867363658, 0.292221537796944, 0.31957488542319,
                            0.190704224192292, 0.180483211648746, 0.080711313679564]]), np.array(
                [0.0167185996454015, 0.0025467077202535, 0.007335432263819, 0.012175439176836, 0.0155537754344845,
                 0.01562855560931, 0.0124078271698325, 0.0070280365352785, 0.0015973380868895, 0.0025467077202535,
                 0.007335432263819, 0.012175439176836, 0.0155537754344845, 0.01562855560931, 0.0124078271698325,
                 0.0070280365352785, 0.0015973380868895, 0.0025467077202535, 0.007335432263819, 0.012175439176836,
                 0.0155537754344845, 0.01562855560931, 0.0124078271698325, 0.0070280365352785, 0.0015973380868895,
                 0.0040598276594965, 0.0134028711415815, 0.009229996605411, 0.004238434267164, 0.0091463983850125,
                 0.0033328160020825, 0.0040598276594965, 0.0134028711415815, 0.009229996605411, 0.004238434267164,
                 0.0091463983850125, 0.0033328160020825, 0.0040598276594965, 0.0134028711415815, 0.009229996605411,
                 0.004238434267164, 0.0091463983850125, 0.0033328160020825, 0.0040598276594965, 0.0134028711415815,
                 0.009229996605411, 0.004238434267164, 0.0091463983850125, 0.0033328160020825, 0.0040598276594965,
                 0.0134028711415815, 0.009229996605411, 0.004238434267164, 0.0091463983850125, 0.0033328160020825,
                 0.0040598276594965, 0.0134028711415815, 0.009229996605411, 0.004238434267164, 0.0091463983850125,
                 0.0033328160020825])),
            17: (np.array([[0.333333333333333, 0.497170540556774, 0.482176322624624, 0.450239969020781,
                            0.400266239377397, 0.252141267970952, 0.162047004658462, 0.0758758822607461,
                            0.015654726967822, 0.005658918886452, 0.035647354750751, 0.099520061958437,
                            0.199467521245206, 0.495717464058095, 0.675905990683077, 0.848248235478508,
                            0.968690546064356, 0.497170540556774, 0.482176322624625, 0.450239969020782,
                            0.400266239377397, 0.252141267970953, 0.162047004658461, 0.075875882260746,
                            0.015654726967822, 0.655493203809423, 0.57233759053202, 0.626001190286227,
                            0.796427214974071, 0.75235100593773, 0.904625504095608, 0.334319867363658,
                            0.292221537796944, 0.31957488542319, 0.190704224192292, 0.180483211648746,
                            0.080711313679564, 0.010186928826919, 0.135440871671036, 0.054423924290583,
                            0.012868560833637, 0.067165782413524, 0.014663182224828, 0.010186928826919,
                            0.135440871671036, 0.054423924290583, 0.012868560833637, 0.067165782413524,
                            0.014663182224828, 0.334319867363658, 0.292221537796944, 0.31957488542319,
                            0.190704224192292, 0.180483211648746, 0.080711313679564, 0.655493203809423,
                            0.57233759053202, 0.626001190286227, 0.796427214974071, 0.75235100593773,
                            0.904625504095608],
                           [0.333333333333333, 0.005658918886452, 0.035647354750751, 0.099520061958437,
                            0.199467521245206, 0.495717464058095, 0.675905990683077, 0.848248235478508,
                            0.968690546064356, 0.497170540556774, 0.482176322624625, 0.450239969020782,
                            0.400266239377397, 0.252141267970953, 0.162047004658461, 0.075875882260746,
                            0.015654726967822, 0.497170540556774, 0.482176322624624, 0.450239969020781,
                            0.400266239377397, 0.252141267970952, 0.162047004658462, 0.0758758822607461,
                            0.015654726967822, 0.010186928826919, 0.135440871671036, 0.054423924290583,
                            0.012868560833637, 0.067165782413524, 0.014663182224828, 0.010186928826919,
                            0.135440871671036, 0.054423924290583, 0.012868560833637, 0.067165782413524,
                            0.014663182224828, 0.334319867363658, 0.292221537796944, 0.31957488542319,
                            0.190704224192292, 0.180483211648746, 0.080711313679564, 0.655493203809423,
                            0.57233759053202, 0.626001190286227, 0.796427214974071, 0.75235100593773, 0.904625504095608,
                            0.655493203809423, 0.57233759053202, 0.626001190286227, 0.796427214974071, 0.75235100593773,
                            0.904625504095608, 0.334319867363658, 0.292221537796944, 0.31957488542319,
                            0.190704224192292, 0.180483211648746, 0.080711313679564]]), np.array(
                [0.0167185996454015, 0.0025467077202535, 0.007335432263819, 0.012175439176836, 0.0155537754344845,
                 0.01562855560931, 0.0124078271698325, 0.0070280365352785, 0.0015973380868895, 0.0025467077202535,
                 0.007335432263819, 0.012175439176836, 0.0155537754344845, 0.01562855560931, 0.0124078271698325,
                 0.0070280365352785, 0.0015973380868895, 0.0025467077202535, 0.007335432263819, 0.012175439176836,
                 0.0155537754344845, 0.01562855560931, 0.0124078271698325, 0.0070280365352785, 0.0015973380868895,
                 0.0040598276594965, 0.0134028711415815, 0.009229996605411, 0.004238434267164, 0.0091463983850125,
                 0.0033328160020825, 0.0040598276594965, 0.0134028711415815, 0.009229996605411, 0.004238434267164,
                 0.0091463983850125, 0.0033328160020825, 0.0040598276594965, 0.0134028711415815, 0.009229996605411,
                 0.004238434267164, 0.0091463983850125, 0.0033328160020825, 0.0040598276594965, 0.0134028711415815,
                 0.009229996605411, 0.004238434267164, 0.0091463983850125, 0.0033328160020825, 0.0040598276594965,
                 0.0134028711415815, 0.009229996605411, 0.004238434267164, 0.0091463983850125, 0.0033328160020825,
                 0.0040598276594965, 0.0134028711415815, 0.009229996605411, 0.004238434267164, 0.0091463983850125,
                 0.0033328160020825])),
            18: (np.array([[0.333333333333333, 0.489609987073007, 0.454536892697892, 0.401416680649431,
                            0.255551654403097, 0.177077942152129, 0.110061053227952, 0.055528624251839,
                            0.012621863777228, 0.020780025853987, 0.090926214604215, 0.197166638701138,
                            0.488896691193805, 0.645844115695741, 0.779877893544096, 0.888942751496321,
                            0.974756272445543, 0.489609987073006, 0.454536892697893, 0.401416680649431,
                            0.255551654403098, 0.17707794215213, 0.110061053227952, 0.05552862425184, 0.012621863777229,
                            0.600633794794645, 0.557603261588784, 0.720987025817365, 0.594527068955871,
                            0.839331473680838, 0.701087978926173, 0.822931324069857, 0.924344252620784,
                            0.395754787356943, 0.307929983880436, 0.26456694840652, 0.358539352205951,
                            0.157807405968595, 0.075050596975911, 0.142421601113383, 0.065494628082938,
                            0.003611417848412, 0.13446675453078, 0.014446025776115, 0.046933578838178,
                            0.002861120350567, 0.223861424097916, 0.03464707481676, 0.010161119296278,
                            0.003611417848412, 0.13446675453078, 0.014446025776115, 0.046933578838178,
                            0.002861120350567, 0.223861424097916, 0.03464707481676, 0.010161119296278,
                            0.395754787356943, 0.307929983880436, 0.26456694840652, 0.358539352205951,
                            0.157807405968595, 0.075050596975911, 0.142421601113383, 0.065494628082938,
                            0.600633794794645, 0.557603261588784, 0.720987025817365, 0.594527068955871,
                            0.839331473680838, 0.701087978926173, 0.822931324069857, 0.924344252620784],
                           [0.333333333333333, 0.020780025853987, 0.090926214604215, 0.197166638701138,
                            0.488896691193805, 0.645844115695741, 0.779877893544096, 0.888942751496321,
                            0.974756272445543, 0.489609987073006, 0.454536892697893, 0.401416680649431,
                            0.255551654403098, 0.17707794215213, 0.110061053227952, 0.05552862425184, 0.012621863777229,
                            0.489609987073007, 0.454536892697892, 0.401416680649431, 0.255551654403097,
                            0.177077942152129, 0.110061053227952, 0.055528624251839, 0.012621863777228,
                            0.003611417848412, 0.13446675453078, 0.014446025776115, 0.046933578838178,
                            0.002861120350567, 0.223861424097916, 0.03464707481676, 0.010161119296278,
                            0.003611417848412, 0.13446675453078, 0.014446025776115, 0.046933578838178,
                            0.002861120350567, 0.223861424097916, 0.03464707481676, 0.010161119296278,
                            0.395754787356943, 0.307929983880436, 0.26456694840652, 0.358539352205951,
                            0.157807405968595, 0.075050596975911, 0.142421601113383, 0.065494628082938,
                            0.600633794794645, 0.557603261588784, 0.720987025817365, 0.594527068955871,
                            0.839331473680838, 0.701087978926173, 0.822931324069857, 0.924344252620784,
                            0.600633794794645, 0.557603261588784, 0.720987025817365, 0.594527068955871,
                            0.839331473680838, 0.701087978926173, 0.822931324069857, 0.924344252620784,
                            0.395754787356943, 0.307929983880436, 0.26456694840652, 0.358539352205951,
                            0.157807405968595, 0.075050596975911, 0.142421601113383, 0.065494628082938]]), np.array(
                [0.0164531656944595, 0.005165365945636, 0.011193623631508, 0.015133062934734, 0.015245483901099,
                 0.0120796063708205, 0.0080254017934005, 0.004042290130892, 0.0010396810137425, 0.005165365945636,
                 0.011193623631508, 0.015133062934734, 0.015245483901099, 0.0120796063708205, 0.0080254017934005,
                 0.004042290130892, 0.0010396810137425, 0.005165365945636, 0.011193623631508, 0.015133062934734,
                 0.015245483901099, 0.0120796063708205, 0.0080254017934005, 0.004042290130892, 0.0010396810137425,
                 0.0019424384524905, 0.012787080306011, 0.004440451786669, 0.0080622733808655, 0.0012459709087455,
                 0.0091214200594755, 0.0051292818680995, 0.001899964427651, 0.0019424384524905, 0.012787080306011,
                 0.004440451786669, 0.0080622733808655, 0.0012459709087455, 0.0091214200594755, 0.0051292818680995,
                 0.001899964427651, 0.0019424384524905, 0.012787080306011, 0.004440451786669, 0.0080622733808655,
                 0.0012459709087455, 0.0091214200594755, 0.0051292818680995, 0.001899964427651, 0.0019424384524905,
                 0.012787080306011, 0.004440451786669, 0.0080622733808655, 0.0012459709087455, 0.0091214200594755,
                 0.0051292818680995, 0.001899964427651, 0.0019424384524905, 0.012787080306011, 0.004440451786669,
                 0.0080622733808655, 0.0012459709087455, 0.0091214200594755, 0.0051292818680995, 0.001899964427651,
                 0.0019424384524905, 0.012787080306011, 0.004440451786669, 0.0080622733808655, 0.0012459709087455,
                 0.0091214200594755, 0.0051292818680995, 0.001899964427651])),
            19: (np.array([[0.333333333333333, 0.489609987073007, 0.454536892697892, 0.401416680649431,
                            0.255551654403097, 0.177077942152129, 0.110061053227952, 0.055528624251839,
                            0.012621863777228, 0.020780025853987, 0.090926214604215, 0.197166638701138,
                            0.488896691193805, 0.645844115695741, 0.779877893544096, 0.888942751496321,
                            0.974756272445543, 0.489609987073006, 0.454536892697893, 0.401416680649431,
                            0.255551654403098, 0.17707794215213, 0.110061053227952, 0.05552862425184, 0.012621863777229,
                            0.600633794794645, 0.557603261588784, 0.720987025817365, 0.594527068955871,
                            0.839331473680838, 0.701087978926173, 0.822931324069857, 0.924344252620784,
                            0.395754787356943, 0.307929983880436, 0.26456694840652, 0.358539352205951,
                            0.157807405968595, 0.075050596975911, 0.142421601113383, 0.065494628082938,
                            0.003611417848412, 0.13446675453078, 0.014446025776115, 0.046933578838178,
                            0.002861120350567, 0.223861424097916, 0.03464707481676, 0.010161119296278,
                            0.003611417848412, 0.13446675453078, 0.014446025776115, 0.046933578838178,
                            0.002861120350567, 0.223861424097916, 0.03464707481676, 0.010161119296278,
                            0.395754787356943, 0.307929983880436, 0.26456694840652, 0.358539352205951,
                            0.157807405968595, 0.075050596975911, 0.142421601113383, 0.065494628082938,
                            0.600633794794645, 0.557603261588784, 0.720987025817365, 0.594527068955871,
                            0.839331473680838, 0.701087978926173, 0.822931324069857, 0.924344252620784],
                           [0.333333333333333, 0.020780025853987, 0.090926214604215, 0.197166638701138,
                            0.488896691193805, 0.645844115695741, 0.779877893544096, 0.888942751496321,
                            0.974756272445543, 0.489609987073006, 0.454536892697893, 0.401416680649431,
                            0.255551654403098, 0.17707794215213, 0.110061053227952, 0.05552862425184, 0.012621863777229,
                            0.489609987073007, 0.454536892697892, 0.401416680649431, 0.255551654403097,
                            0.177077942152129, 0.110061053227952, 0.055528624251839, 0.012621863777228,
                            0.003611417848412, 0.13446675453078, 0.014446025776115, 0.046933578838178,
                            0.002861120350567, 0.223861424097916, 0.03464707481676, 0.010161119296278,
                            0.003611417848412, 0.13446675453078, 0.014446025776115, 0.046933578838178,
                            0.002861120350567, 0.223861424097916, 0.03464707481676, 0.010161119296278,
                            0.395754787356943, 0.307929983880436, 0.26456694840652, 0.358539352205951,
                            0.157807405968595, 0.075050596975911, 0.142421601113383, 0.065494628082938,
                            0.600633794794645, 0.557603261588784, 0.720987025817365, 0.594527068955871,
                            0.839331473680838, 0.701087978926173, 0.822931324069857, 0.924344252620784,
                            0.600633794794645, 0.557603261588784, 0.720987025817365, 0.594527068955871,
                            0.839331473680838, 0.701087978926173, 0.822931324069857, 0.924344252620784,
                            0.395754787356943, 0.307929983880436, 0.26456694840652, 0.358539352205951,
                            0.157807405968595, 0.075050596975911, 0.142421601113383, 0.065494628082938]]), np.array(
                [0.0164531656944595, 0.005165365945636, 0.011193623631508, 0.015133062934734, 0.015245483901099,
                 0.0120796063708205, 0.0080254017934005, 0.004042290130892, 0.0010396810137425, 0.005165365945636,
                 0.011193623631508, 0.015133062934734, 0.015245483901099, 0.0120796063708205, 0.0080254017934005,
                 0.004042290130892, 0.0010396810137425, 0.005165365945636, 0.011193623631508, 0.015133062934734,
                 0.015245483901099, 0.0120796063708205, 0.0080254017934005, 0.004042290130892, 0.0010396810137425,
                 0.0019424384524905, 0.012787080306011, 0.004440451786669, 0.0080622733808655, 0.0012459709087455,
                 0.0091214200594755, 0.0051292818680995, 0.001899964427651, 0.0019424384524905, 0.012787080306011,
                 0.004440451786669, 0.0080622733808655, 0.0012459709087455, 0.0091214200594755, 0.0051292818680995,
                 0.001899964427651, 0.0019424384524905, 0.012787080306011, 0.004440451786669, 0.0080622733808655,
                 0.0012459709087455, 0.0091214200594755, 0.0051292818680995, 0.001899964427651, 0.0019424384524905,
                 0.012787080306011, 0.004440451786669, 0.0080622733808655, 0.0012459709087455, 0.0091214200594755,
                 0.0051292818680995, 0.001899964427651, 0.0019424384524905, 0.012787080306011, 0.004440451786669,
                 0.0080622733808655, 0.0012459709087455, 0.0091214200594755, 0.0051292818680995, 0.001899964427651,
                 0.0019424384524905, 0.012787080306011, 0.004440451786669, 0.0080622733808655, 0.0012459709087455,
                 0.0091214200594755, 0.0051292818680995, 0.001899964427651])),
        }[norder]
    except:
        raise NotImplementedError("get_quadrature_tri: The requested order of quadrature is not implemented!")


def get_quadrature_line(norder: int) -> Tuple[np.ndarray, np.ndarray]:
    """Return a nth order accurate quadrature rule for line [0,1]."""
    if norder <= 1:
        norder = 2
    X, W = np.polynomial.legendre.leggauss(int(np.ceil((norder + 1.0)/2.0)))
    return np.array([0.5*X + 0.5]), W/2.0


def get_quadrature_point(norder: int = 0) -> Tuple[np.ndarray, np.ndarray]:
    """Return the quadrature rule for the point []."""
    return np.zeros((0, 1)), np.ones(1)
